#ifndef DATABASE_ALLOC_H
#define DATABASE_ALLOC_H

#include "../base/Singleton.hpp"
#include "../base/Defind.hpp"

#include <unordered_set>

namespace DBServer
{
namespace Database
{

typedef char Block;
struct Page;
struct Pool;
class Alloc;

typedef struct Page {
    char            *page;                  // next page in the memory pool
    char            *cur_block;             // next free block in this page
    int             free_num;
                                            // the num of the free block
    void init(const int);                   // init a memory page and add it into the memory pool
    void release();                         // release a memory page and push it into the memory pool
} Page;

typedef struct Pool {
    Page**                  pages;
    unsigned long           page_size;
    int                     using_page;
    int                     page_num;
    int                     block_size;
    int                     use_block;

    void init(int);
    void destory();
    Block* New();
    void Delete(Block*);
} Pool;

class Alloc : public DBServer::Base::Singleton<Alloc> {
friend class DBServer::Base::Singleton<Alloc>;
public:

    Block* New(int);
    void Delete(Block*);

    ~Alloc();

    Alloc(const Alloc&) = delete;
    Alloc(const Alloc&&) = delete;
    Alloc& operator=(const Alloc&) = delete;
    Alloc&& operator=(const Alloc&&) = delete;
protected:
    Alloc();

private:
    Pool *POOL_LIST[PAGE_TYPE_NUM];
    int BLOCK_TYPE[PAGE_TYPE_NUM];
    std::unordered_set<char*> map[PAGE_TYPE_NUM];

};


} // namespace Database
} // namespace DBServer



#endif